using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Data;

namespace Pixysoft.Data
{
    public class TreeNodeTableMapping : ContextBoundObject
    {
        private TreeNodeTableMapping() { }
        private static TreeNodeTableMapping instance;
        public static TreeNodeTableMapping Instance
        {
            get
            {
                if (instance == null)
                    instance = new TreeNodeTableMapping();
                return instance;
            }
        }

        public TreeNode GetTreeNodeByDFS(DataTable table, string nodeColumn, string parentColumn)
        {
            TreeNode root = new TreeNode();

            TreeNode parent = root;

            foreach (DataRow row in table.Rows)
            {
                string parentname = row[parentColumn].ToString().Trim();

                string nodename = row[nodeColumn].ToString().Trim();

                TreeNode node = new TreeNode(nodename);

                node.Name = nodename;

                if (parentname == "")
                {
                    parent.Nodes.Add(node);
                    parent = node;
                }
                else if (parentname == parent.Name)
                {
                    parent.Nodes.Add(node);
                    parent = node;
                }
                else
                {
                    while (parent.Name != parentname && parent.Parent != null)
                        parent = parent.Parent;

                    if (parentname == parent.Name || parent.Name == "")
                    {
                        parent.Nodes.Add(node);
                        parent = node;
                    }
                    else
                        throw new Exception("Unknown Tree Structure");
                }
            }

            return root;
        }

        public DataTable GetTableByDFS(TreeNode node)
        {
            DataTable table = new DataTable();
            table.Columns.Add("ID");
            table.Columns.Add("TPARENTID");
            table.Columns.Add("TPARENTNAME");
            table.Columns.Add("TNODEID");
            table.Columns.Add("TNODENAME");
            table.Columns.Add("LFT");
            table.Columns.Add("RGT");

            int counter = 1;

            SearchNodeByDFS(node.Clone() as TreeNode, table, ref  counter);


            return table;
        }

        private void SearchNodeByDFS(TreeNode node, DataTable table, ref  int counter)
        {
            node.ImageIndex = counter;

            counter++;

            foreach (TreeNode child in node.Nodes)
            {
                SearchNodeByDFS(child, table, ref counter);

                if (!child.Checked)
                {
                    child.SelectedImageIndex = counter;

                    counter++;

                    table.Rows.Add(NodeToRow(child, table));

                    child.Checked = true;
                }
            }

            if (!node.Checked)
            {
                node.SelectedImageIndex = counter;

                counter++;

                table.Rows.Add(NodeToRow(node, table));

                node.Checked = true;
            }

        }

        private DataRow NodeToRow(TreeNode node, DataTable table)
        {
            DataRow row = table.NewRow();

            row["TPARENTID"] = node.Parent != null ? node.Parent.Name : null;
            row["TPARENTNAME"] = node.Parent != null ? node.Parent.Text : null;

            row["TNODEID"] = node.Name;
            row["TNODENAME"] = node.Text;

            row["LFT"] = node.ImageIndex;
            row["RGT"] = node.SelectedImageIndex;

            return row;
        }


    }
}
